function params = gradientDescent(data, labels, initParams, lr=3, vdata=[], allParams=[], paramsInd=-1, iterations=100, stagLimit=6, sensitivityThreshold=0.0001 )
    iteration=0;
    stagnant=-1;    
    
    params=initParams;
    costDerivativeEst=sensitivityThreshold+1;

    lRate = ones(1,size(data,2));
    lRate = lRate.*lr;

    down = 0.5;
    up   = 1.01;       

    prevSigns=sign(costDer(data,labels,params));

    prevQuality=0;

    vlabels=[];
    if(!isempty(vdata))
        vlabels = vdata(:,1);
        vdata(:,1)=[];            
        prevQuality=verify(vdata, vlabels, [allParams(1:paramsInd-1,:); params; allParams(paramsInd+1:end,:)]);
    endif;
    
    while(costDerivativeEst>sensitivityThreshold)
        iteration+=1;
        stagnant+=1;       
        
        if(paramsInd!=-1)
            printf("classifier: %d, ",paramsInd);
        endif;
        
        printf("iteration: %d/%d, stagnation count: %d",iteration,iterations,stagnant);
        #evaluate the stagnation criterion
        if(stagnant>0)
            stagLimit=stagnationCriterion(iterations,iteration,stagLimit);            
            printf("/%f",ceil(stagLimit));
            if(stagnant>stagLimit)
                printf(" reached.\n");            
                break;        
            endif;
        endif;
        

        dcost=costDer(data,labels,params);
        signs=sign(dcost);

        costDerivativeEst = sum(abs(dcost),2);
        printf(", dcost: %f", costDerivativeEst)


        modifiers=signs.*prevSigns;
        lRate(modifiers==-1).*=down;
        lRate(modifiers==1 ).*=up;
        prevSigns=signs;

        params=params.-(lRate.*dcost);

        #update the history
        if(!isempty(vdata))        
            quality = verify(vdata, vlabels, [allParams(1:paramsInd-1,:); params; allParams(paramsInd+1:end,:)]);
            printf(", quality: %f",quality);
            if(quality!=prevQuality)
                if(quality>prevQuality)
                    stagnant=-1;
                endif;
                prevQuality=quality;
            endif;
        elseif(iteration>=iterations)
            printf("\n");    
            break;
        endif;
        printf("\n");
        fflush(stdout);
    end;
end;
